package org.jeecg.modules.hc.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.hc.entity.HcMerchant;
import org.jeecg.modules.hc.entity.HcOrderDetailed;
import org.jeecg.modules.hc.entity.HcSiteRelation;
import org.jeecg.modules.hc.enums.HcBusinessStateEnum;
import org.jeecg.modules.hc.enums.HcDeliveryStatusEnum;
import org.jeecg.modules.hc.enums.HcStoreStatusEnum;
import org.jeecg.modules.hc.service.IHcMerchantService;
import org.jeecg.modules.hc.service.IHcOrderMerchantService;
import org.jeecg.modules.hc.service.IHcSiteRelationService;
import org.jeecg.modules.hc.utils.HcUtils;
import org.jeecg.modules.hc.utils.PayCommonUtil;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.jeecg.modules.system.model.DuplicateCheckVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 商户
 * @Author: jeecg-boot
 * @Date: 2022-12-13
 * @Version: V1.0
 */
@Api(tags = "商户")
@RestController
@RequestMapping("/hc/hcMerchant")
@Slf4j
public class HcMerchantController extends JeecgController<HcMerchant, IHcMerchantService> {
    @Autowired
    private IHcMerchantService hcMerchantService;

    @Autowired
    private SysDictMapper sysDictMapper;

    @Autowired
    private IHcOrderMerchantService hcOrderMerchantService;

    @Autowired
    private IHcSiteRelationService hcSiteRelationService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private WxMpService mpService;

    @ApiOperation("同步商品信息到redis")
    @GetMapping("/syncCommodityToRedis")
    public Result<?> syncCommodityToRedis() {
        long start = System.currentTimeMillis();
//        hcMerchantService.syncCommodityToRedis();
        log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
        return Result.ok();
    }

    @ApiOperation("设置微信openId")
    @GetMapping("/setOpenId")
    public Result<?> setOpenId(@RequestParam String code) throws WxErrorException {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        System.out.println(sysUser);
        hcMerchantService.setOpenId(code, sysUser.getId());
        return Result.ok();
    }

    @ApiOperation("小程序设置微信openId")
    @GetMapping("/setOpenIdByMiNi")
    public Result<?> setOpenIdByMiNi(@RequestParam String openId) throws WxErrorException {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        System.out.println(sysUser);
        hcMerchantService.updateById(new HcMerchant().setId(sysUser.getId()).setOpenId(openId));
        return Result.ok();
    }

    @ApiOperation("小程序设置微信openId通过code")
    @GetMapping("/setOpenIdByCode")
    public Result<?> setOpenIdByCode(@RequestParam String code) throws WxErrorException {
         String openId = null;
         String resultOpen = PayCommonUtil.sendGet("https://api.weixin.qq.com/sns/jscode2session",
                 "appid=" + "wx7280e609bff3da8f" +//小程序ID
                         "&secret="+ "1a7c43dc57e5295c619f904082ac2b25" + //小程序密钥
                         "&js_code="+ code + //前端 传入 code
                         "&grant_type=authorization_code");
         JSONObject jsonObject = JSONObject.parseObject(resultOpen);
         if (jsonObject.containsKey("errcode")) {
             log.info("code无效，openId获取失败——小程序获取");
         }
        openId = jsonObject.get("openid").toString();
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        System.out.println(sysUser);
        hcMerchantService.updateById(new HcMerchant().setId(sysUser.getId()).setOpenId(openId));
        return Result.ok();
    }

    @ApiOperation("根据商家id获取token")
    @GetMapping("/getTokenById")
    public Result<?> getTokenById(@RequestParam String id) {
        return Result.ok(hcMerchantService.getTokenById(id));
    }

    @ApiOperation("全局页面修改商家配送状态")
    @PostMapping("/editDeliveryStatus")
    public Result<?> editDeliveryStatus(@RequestBody HcMerchant param) {

        HcMerchant hcMerchant = hcMerchantService.getById(param.getId());

        if (hcMerchant == null) {
            return Result.error("未找到对应数据");
        }

        HcMerchant hcMerchantUpd = new HcMerchant().setId(hcMerchant.getId()).setDeliveryStatus(HcDeliveryStatusEnum.YES);
        hcMerchantService.updateById(hcMerchantUpd);
        return Result.ok(hcMerchantUpd);
    }

    @ApiOperation("获取全局页面商户列表")
    @GetMapping("/getMerchantListOfGlobalPage")
    public Result<?> getMerchantListOfGlobalPage(HcMerchant param,
                                                 @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<HcMerchant> page = new Page<HcMerchant>(pageNo, pageSize);
        LambdaQueryWrapper<HcMerchant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(HcMerchant::getId,
                HcMerchant::getLogo,
                HcMerchant::getStoreName,
                HcMerchant::getStoreStatus,
                HcMerchant::getBusinessState,
                HcMerchant::getBusinessHours,
                HcMerchant::getDeliveryStatus
        );

        if (StringUtils.isNotBlank(param.getSiteId())) {
            List<HcSiteRelation> siteRelationList = hcSiteRelationService.list(new LambdaQueryWrapper<HcSiteRelation>()
                    .select(HcSiteRelation::getMerchantId)
                    .eq(HcSiteRelation::getSiteId, param.getSiteId())
            );

            List<String> collect = siteRelationList.stream().map(HcSiteRelation::getMerchantId).collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(collect)) {
                queryWrapper.in(HcMerchant::getId, collect);
            } else {
                IPage<HcMerchant> pageList = new Page<>();
                return Result.OK(pageList);
            }
        }

        if (param.getStoreStatus() != null) {
            queryWrapper.eq(HcMerchant::getStoreStatus, param.getStoreStatus());
        }

        if (param.getDeliveryStatus() != null) {
            queryWrapper.eq(HcMerchant::getDeliveryStatus, param.getDeliveryStatus());
        }

        queryWrapper.last(" order by BUSINESS_STATE desc, ID ");

        Page<HcMerchant> hcMerchantPage = hcMerchantService.page(page, queryWrapper);

        JSONObject yongShanTuanTime = HcUtils.getYongShanTuanTime();

        for (HcMerchant record : hcMerchantPage.getRecords()) {

            long count;//销量
            HcMerchant orderStatistics = hcOrderMerchantService.getOrderStatistics(record.getId());
            List<HcOrderDetailed> hcOrderDetailedList = orderStatistics.getHcOrderDetailedList();
            count = hcOrderDetailedList.stream().mapToLong(HcOrderDetailed::getCommodityQuantity).sum();

//            long count = hcOrderMerchantService.count(new LambdaQueryWrapper<HcOrderMerchant>()
//                    .eq(HcOrderMerchant::getMerchantId, record.getId())
//                    .between(HcOrderMerchant::getCreateTime, yongShanTuanTime.getString("beginTime"), yongShanTuanTime.getString("endTime"))
//                    .in(HcOrderMerchant::getState, HcOrderStateEnum.COMPLETED, HcOrderStateEnum.PAY)
//            );

            record.setStoreSales(count);

//            HcOrderMerchant hcOrderMerchant = hcOrderMerchantService.getOne(new LambdaQueryWrapper<HcOrderMerchant>()
//                    .eq(HcOrderMerchant::getMerchantId, record.getId())
//                    .orderByDesc(HcOrderMerchant::getCreateTime)
//                    .last(" limit 1 ")
//            );
//
//            if (hcOrderMerchant != null) {
//                record.setGlobalPageDate(new SimpleDateFormat("MM-dd HH:mm").format(hcOrderMerchant.getCreateTime()));
//            }

            hcMerchantService.setInformation(record);
        }

        return Result.ok(hcMerchantPage);
    }

    @ApiOperation("登录")
    @GetMapping("/login")
    public Result<?> login(@RequestParam String phone, String pass) {
        return Result.ok(hcMerchantService.login(phone, pass));
    }

    @ApiOperation(value = "用户端首页获取商户和菜品列表", notes="两种场景下调用此接口：<br/>1. 当用户点击 https://www.yonghsantuan.com 打开点餐页面时;<br/> 2.当用户在点餐页面选择某个主品类时，比如中餐，轻食 ")
    @GetMapping("/getList")
    public Result<?> getList(HcMerchant param,
                             @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                             @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<HcMerchant> page = new Page<HcMerchant>(pageNo, pageSize);
        // 用户所在大厦地址id
        if (StringUtils.isBlank(param.getAddressId())) {
            return Result.ok();
        }

        return Result.ok(hcMerchantService.getList(page, param));
    }

    @ApiOperation("用户端根据商户id获取菜品")
    @GetMapping("/queryCommodityByMerchantId")
    public Result<?> queryCommodityByMerchantId(HcMerchant param) {
        if (StringUtils.isBlank(param.getAddressId())) {
            return Result.ok();
        }

        return Result.ok(hcMerchantService.queryCommodityByMerchantId(param));
    }

    @ApiOperation("修改商家门店状态")
    @PostMapping("/editStoreStatus")
    public Result<?> editStoreStatus(@RequestBody HcMerchant param) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        HcMerchant hcMerchant = hcMerchantService.getById(sysUser.getId());

        if (hcMerchant == null) {
            return Result.error("未找到对应数据");
        }

        if (param.getStoreStatus().equals(HcStoreStatusEnum.WAIT)) {
            if (!hcMerchant.getStoreStatus().equals(HcStoreStatusEnum.NO)) {
                return Result.error("未接单状态时才能更改状态为接单");
            }
        } else if (param.getStoreStatus().equals(HcStoreStatusEnum.YES)) {
            if (!hcMerchant.getStoreStatus().equals(HcStoreStatusEnum.WAIT)) {
                return Result.error("出餐中状态时才能更改状态为已出餐");
            }
        } else {
            return Result.error("状态参数错误");
        }

        HcMerchant hcMerchantUpd = new HcMerchant().setId(hcMerchant.getId()).setStoreStatus(param.getStoreStatus());
        hcMerchantService.updateById(hcMerchantUpd);
        return Result.ok(hcMerchantUpd);
    }

    /**
     * 分页列表查询
     *
     * @param hcMerchant
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "商户-分页列表查询")
    @ApiOperation(value = "商户-分页列表查询", notes = "商户-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<HcMerchant>> queryPageList(HcMerchant hcMerchant,
                                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                   HttpServletRequest req) {
        LambdaQueryWrapper<HcMerchant> queryWrapper = new LambdaQueryWrapper<>();

        if (hcMerchant.getStoreStatus() != null) {
            queryWrapper.like(HcMerchant::getStoreStatus, hcMerchant.getStoreStatus());
        }

        if (StringUtils.isNotBlank(hcMerchant.getStoreName())) {
            queryWrapper.like(HcMerchant::getStoreName, hcMerchant.getStoreName());
        }

        if (hcMerchant.getBusinessState() != null) {
            if (hcMerchant.getBusinessState() == HcBusinessStateEnum.NO) {
                queryWrapper.in(HcMerchant::getBusinessState, HcBusinessStateEnum.NO, HcBusinessStateEnum.NO_ADMIN);
            } else {
                queryWrapper.eq(HcMerchant::getBusinessState, hcMerchant.getBusinessState());
            }
        }

        if (StringUtils.isNotBlank(hcMerchant.getSiteId())) {
            // select  merchant_id from hc_site_relation where site_id = 'xxxx'; 仅返回某个站点内的店铺id 列表
            List<HcSiteRelation> siteRelationList = hcSiteRelationService.list(new LambdaQueryWrapper<HcSiteRelation>()
                    .select(HcSiteRelation::getMerchantId)
                    .eq(HcSiteRelation::getSiteId, hcMerchant.getSiteId())
            );

            List<String> collect = siteRelationList.stream().map(HcSiteRelation::getMerchantId).collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(collect)) {
                queryWrapper.in(HcMerchant::getId, collect);
            } else {
                IPage<HcMerchant> pageList = new Page<>();
                return Result.OK(pageList);
            }
        }

        Page<HcMerchant> page = new Page<HcMerchant>(pageNo, pageSize);

        IPage<HcMerchant> pageList = hcMerchantService.page(page, queryWrapper);

        for (HcMerchant record : pageList.getRecords()) {
            hcMerchantService.setInformation(record);
        }

        return Result.OK(pageList);
    }


    /**
     * 分页列表查询
     *
     * @param hcMerchant
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "商户-分页列表查询")
    @ApiOperation(value = "商户-分页列表查询", notes = "商户-分页列表查询")
    @GetMapping(value = "/merchantList")
    public Result<IPage<HcMerchant>> queryMerchantPageList(HcMerchant hcMerchant,
                                                           @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                           @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                           HttpServletRequest req) {
        QueryWrapper<HcMerchant> queryWrapper = QueryGenerator.initQueryWrapper(hcMerchant, req.getParameterMap());
        Page<HcMerchant> page = new Page<HcMerchant>(pageNo, pageSize);
        IPage<HcMerchant> pageList = hcMerchantService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 分页列表查询
     *
     * @param hcMerchant
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "商户-分页列表查询")
    @ApiOperation(value = "商户-分页列表查询", notes = "商户-分页列表查询")
    @GetMapping(value = "/listNew")
    public Result<IPage<HcMerchant>> queryPageListNew(HcMerchant hcMerchant,
                                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                   HttpServletRequest req) {
        LambdaQueryWrapper<HcMerchant> queryWrapper = new LambdaQueryWrapper<>();

        if (hcMerchant.getStoreStatus() != null) {
            queryWrapper.like(HcMerchant::getStoreStatus, hcMerchant.getStoreStatus());
        }

        if (StringUtils.isNotBlank(hcMerchant.getStoreName())) {
            queryWrapper.like(HcMerchant::getStoreName, hcMerchant.getStoreName());
        }

        if (hcMerchant.getBusinessState() != null) {
            if (hcMerchant.getBusinessState() == HcBusinessStateEnum.NO) {
                queryWrapper.in(HcMerchant::getBusinessState, HcBusinessStateEnum.NO, HcBusinessStateEnum.NO_ADMIN);
            } else {
                queryWrapper.eq(HcMerchant::getBusinessState, hcMerchant.getBusinessState());
            }
        }

        if (StringUtils.isNotBlank(hcMerchant.getSiteId())) {
            List<HcSiteRelation> siteRelationList = hcSiteRelationService.list(new LambdaQueryWrapper<HcSiteRelation>()
                    .select(HcSiteRelation::getMerchantId)
                    .eq(HcSiteRelation::getSiteId, hcMerchant.getSiteId())
            );

            List<String> collect = siteRelationList.stream().map(HcSiteRelation::getMerchantId).collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(collect)) {
                queryWrapper.in(HcMerchant::getId, collect);
            } else {
                IPage<HcMerchant> pageList = new Page<>();
                return Result.OK(pageList);
            }
        }

        Page<HcMerchant> page = new Page<HcMerchant>(pageNo, pageSize);

        IPage<HcMerchant> pageList = hcMerchantService.page(page, queryWrapper);

        for (HcMerchant record : pageList.getRecords()) {
            hcMerchantService.setInformation(record);
        }

        return Result.OK(pageList);
    }
    /**
     * 添加
     *
     * @param hcMerchant
     * @return
     */
    @AutoLog(value = "商户-添加")
    @ApiOperation(value = "商户-添加", notes = "商户-添加")
    //@RequiresPermissions("org.jeecg.modules:hc_merchant:add")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody HcMerchant hcMerchant) {

        DuplicateCheckVo duplicateCheckVo = new DuplicateCheckVo();
        duplicateCheckVo.setTableName("HC_MERCHANT");
        duplicateCheckVo.setFieldName("LOGIN_ACCOUNT");
        duplicateCheckVo.setFieldVal(hcMerchant.getLoginAccount());
        Long num = sysDictMapper.duplicateCheckCountSqlNoDataId(duplicateCheckVo);

        if (num != null && num > 0) {
            throw new JeecgBootException("门店登录账号已存在");
        }

        hcMerchantService.add(hcMerchant);
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param hcMerchant
     * @return
     */
    @AutoLog(value = "商户-编辑")
    @ApiOperation(value = "商户-编辑", notes = "商户-编辑")
    //@RequiresPermissions("org.jeecg.modules:hc_merchant:edit")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody HcMerchant hcMerchant) {
        DuplicateCheckVo duplicateCheckVo = new DuplicateCheckVo();
        duplicateCheckVo.setTableName("HC_MERCHANT");
        duplicateCheckVo.setFieldName("LOGIN_ACCOUNT");
        duplicateCheckVo.setFieldVal(hcMerchant.getLoginAccount());
        duplicateCheckVo.setDataId(hcMerchant.getId());
        Long num = sysDictMapper.duplicateCheckCountSql(duplicateCheckVo);

        if (num != null && num > 0) {
            throw new JeecgBootException("门店登录账号已存在！");
        }

        hcMerchantService.edit(hcMerchant);
        return Result.OK("编辑成功!");
    }

    @AutoLog(value = "编辑营业状态")
    @ApiOperation("编辑营业状态")
    //@RequiresPermissions("org.jeecg.modules:hc_merchant:edit")
    @PostMapping("/editState")
    public Result<String> editState(@RequestBody HcMerchant hcMerchant) {
        hcMerchantService.updateById(new HcMerchant().setId(hcMerchant.getId()).setBusinessState(hcMerchant.getBusinessState()));
        return Result.OK("修改成功，如果改为营业中没有变更则说明不在营业时间内");
    }

    @AutoLog(value = "批量编辑营业状态")
    @ApiOperation("批量编辑营业状态")
    @PostMapping("/editStateBatch")
    public Result<String> editStateBatch(@RequestBody HcMerchant param) {
        List<String> ids = Arrays.asList(param.getSelections().split(","));

        hcMerchantService.update(new HcMerchant().setBusinessState(param.getBusinessState()),
                new LambdaQueryWrapper<HcMerchant>().in(HcMerchant::getId, ids)
        );

        return Result.OK("修改成功，如果改为营业中没有变更则说明不在营业时间内");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "商户-通过id删除")
    @ApiOperation(value = "商户-通过id删除", notes = "商户-通过id删除")
    //@RequiresPermissions("org.jeecg.modules:hc_merchant:delete")
    @DeleteMapping(value = "/delete")
    @Transactional(rollbackFor = Exception.class)
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        HcMerchant hcMerchant = hcMerchantService.getById(id);
        hcMerchantService.updateById(new HcMerchant().setId(id).setLoginAccount(hcMerchant.getLoginAccount() + "-" + System.currentTimeMillis()));
        hcMerchantService.removeById(id);
        redisUtil.del(CacheConstant.HC_MERCHANT_CACHE + "::" + hcMerchant.getLoginAccount());
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
//    @AutoLog(value = "商户-批量删除")
//    @ApiOperation(value = "商户-批量删除", notes = "商户-批量删除")
    //@RequiresPermissions("org.jeecg.modules:hc_merchant:deleteBatch")
//    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.hcMerchantService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    //@AutoLog(value = "商户-通过id查询")
    @ApiOperation(value = "商户-通过id查询", notes = "商户-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<HcMerchant> queryById(@RequestParam(name = "id", required = false) String id) {
        if (StringUtils.isBlank(id)) {
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            id = sysUser.getId();
        }

        HcMerchant hcMerchant = hcMerchantService.getById(id);

        if (hcMerchant == null) {
            return Result.error("未找到对应数据");
        }

        hcMerchantService.setInformation(hcMerchant);

        return Result.OK(hcMerchant);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param hcMerchant
     */
    //@RequiresPermissions("org.jeecg.modules:hc_merchant:exportXls")
//    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, HcMerchant hcMerchant) {
        return super.exportXls(request, hcMerchant, HcMerchant.class, "商户");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    //@RequiresPermissions("hc_merchant:importExcel")
//    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, HcMerchant.class);
    }
}
